home *** CD-ROM | disk | FTP | other *** search
/ PC/CD Gamer UK 120 / CD Gamer Issue 120 (March 2003) (Disc 2).ISO / mods / Q2_Codered / codeRED1_0.exe / Data1.cab / r_mesh.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-09-24  |  18.7 KB  |  789 lines

  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */ 
  20. // r_mesh.c: triangle model functions
  21.  
  22. #include "r_local.h"
  23.  
  24. /*
  25. =============================================================
  26.  
  27.   ALIAS MODELS
  28.  
  29. =============================================================
  30. */
  31.  
  32. #define NUMVERTEXNORMALS    162
  33.  
  34. float    r_avertexnormals[NUMVERTEXNORMALS][3] = {
  35. #include "anorms.h"
  36. };
  37.  
  38. typedef float vec4_t[4];
  39.  
  40. static    vec4_t    s_lerped[MAX_VERTS];
  41. //static    vec3_t    lerped[MAX_VERTS];
  42.  
  43. vec3_t    shadevector;
  44. float    shadelight[3];
  45.  
  46. // precalculated dot products for quantized angles
  47. #define SHADEDOT_QUANT 16
  48. float    r_avertexnormal_dots[SHADEDOT_QUANT][256] =
  49. #include "anormtab.h"
  50. ;
  51.  
  52. float    *shadedots = r_avertexnormal_dots[0];
  53.  
  54. void GL_LerpVerts( int nverts, dtrivertx_t *v, dtrivertx_t *ov, dtrivertx_t *verts, float *lerp, float move[3], float frontv[3], float backv[3] )
  55. {
  56.     int i;
  57.  
  58.     //PMM -- added RF_SHELL_DOUBLE, RF_SHELL_HALF_DAM
  59.     if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) )
  60.     {
  61.         for (i=0 ; i < nverts; i++, v++, ov++, lerp+=4 )
  62.         {
  63.             float *normal = r_avertexnormals[verts[i].lightnormalindex];
  64.  
  65.             lerp[0] = move[0] + ov->v[0]*backv[0] + v->v[0]*frontv[0] + normal[0] * POWERSUIT_SCALE;
  66.             lerp[1] = move[1] + ov->v[1]*backv[1] + v->v[1]*frontv[1] + normal[1] * POWERSUIT_SCALE;
  67.             lerp[2] = move[2] + ov->v[2]*backv[2] + v->v[2]*frontv[2] + normal[2] * POWERSUIT_SCALE; 
  68.         }
  69.     }
  70.     else
  71.     {
  72.         for (i=0 ; i < nverts; i++, v++, ov++, lerp+=4)
  73.         {
  74.             lerp[0] = move[0] + ov->v[0]*backv[0] + v->v[0]*frontv[0];
  75.             lerp[1] = move[1] + ov->v[1]*backv[1] + v->v[1]*frontv[1];
  76.             lerp[2] = move[2] + ov->v[2]*backv[2] + v->v[2]*frontv[2];
  77.         }
  78.     }
  79.  
  80. }
  81.  
  82. /*
  83. =============
  84. GL_DrawAliasFrameLerp
  85.  
  86. interpolates between two frames and origins
  87. FIXME: batch lerp all vertexes
  88. =============
  89. */
  90. void GL_DrawAliasFrameLerp (dmdl_t *paliashdr, float backlerp)
  91. {
  92.     float     l;
  93.     daliasframe_t    *frame, *oldframe;
  94.     dtrivertx_t    *v, *ov, *verts;
  95.     int        *order;
  96.     int        count;
  97.     float    frontlerp;
  98.     float    alpha;
  99.     vec3_t    move, delta, vectors[3];
  100.     vec3_t    frontv, backv;
  101.     int        i;
  102.     int        index_xyz;
  103.     float    *lerp;
  104.  
  105.     frame = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames 
  106.         + currententity->frame * paliashdr->framesize);
  107.     verts = v = frame->verts;
  108.  
  109.     oldframe = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames 
  110.         + currententity->oldframe * paliashdr->framesize);
  111.     ov = oldframe->verts;
  112.  
  113.     order = (int *)((byte *)paliashdr + paliashdr->ofs_glcmds);
  114.  
  115.     if (currententity->flags & RF_TRANSLUCENT)
  116.         alpha = currententity->alpha;
  117.     else
  118.         alpha = 1.0;
  119.  
  120.     // PMM - added double shell
  121.     if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) )
  122.         GL_Bind(r_shelltexture->texnum);  // add this line
  123.  
  124.     frontlerp = 1.0 - backlerp;
  125.  
  126.     // move should be the delta back to the previous frame * backlerp
  127.     VectorSubtract (currententity->oldorigin, currententity->origin, delta);
  128.     AngleVectors (currententity->angles, vectors[0], vectors[1], vectors[2]);
  129.  
  130.     move[0] = DotProduct (delta, vectors[0]);    // forward
  131.     move[1] = -DotProduct (delta, vectors[1]);    // left
  132.     move[2] = DotProduct (delta, vectors[2]);    // up
  133.  
  134.     VectorAdd (move, oldframe->translate, move);
  135.  
  136.     for (i=0 ; i<3 ; i++)
  137.     {
  138.         move[i] = backlerp*move[i] + frontlerp*frame->translate[i];
  139.     }
  140.  
  141.     for (i=0 ; i<3 ; i++)
  142.     {
  143.         frontv[i] = frontlerp*frame->scale[i];
  144.         backv[i] = backlerp*oldframe->scale[i];
  145.     }
  146.  
  147.     lerp = s_lerped[0];
  148.  
  149.     GL_LerpVerts( paliashdr->num_xyz, v, ov, verts, lerp, move, frontv, backv );
  150.  
  151.     if ( gl_vertex_arrays->value )
  152.     {
  153.         float colorArray[MAX_VERTS*4];
  154.  
  155.         qglEnableClientState( GL_VERTEX_ARRAY );
  156.         qglVertexPointer( 3, GL_FLOAT, 16, s_lerped );    // padded for SIMD
  157.  
  158. //        if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE ) )
  159.         // PMM - added double damage shell
  160.         if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) )
  161.         {
  162.             qglColor4f( shadelight[0], shadelight[1], shadelight[2], alpha );
  163.         }
  164.         else
  165.         {
  166.             qglEnableClientState( GL_COLOR_ARRAY );
  167.             qglColorPointer( 3, GL_FLOAT, 0, colorArray );
  168.  
  169.             //
  170.             // pre light everything
  171.             //
  172.             for ( i = 0; i < paliashdr->num_xyz; i++ )
  173.             {
  174.                 float l = shadedots[verts[i].lightnormalindex];
  175.  
  176.                 colorArray[i*3+0] = l * shadelight[0];
  177.                 colorArray[i*3+1] = l * shadelight[1];
  178.                 colorArray[i*3+2] = l * shadelight[2];
  179.             }
  180.         }
  181.  
  182.         if ( qglLockArraysEXT != 0 )
  183.             qglLockArraysEXT( 0, paliashdr->num_xyz );
  184.  
  185.         while (count = *order++)
  186.         {
  187.             // get the vertex count and primitive type
  188.             if (count < 0)
  189.             {
  190.                 count = -count;
  191.                 qglBegin (GL_TRIANGLE_FAN);
  192.             }
  193.             else
  194.             {
  195.                 qglBegin (GL_TRIANGLE_STRIP);
  196.             }
  197.  
  198.             // PMM - added double damage shell
  199.             if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) )
  200.             {
  201.                 do
  202.                 {
  203.                     index_xyz = order[2];
  204.                     order += 3;
  205.  
  206.                     // c14 added the line below
  207.                     qglTexCoord2f (
  208.                         (s_lerped[index_xyz][1] + s_lerped[index_xyz][0]) * (1.0f / 40.0f),
  209.                         s_lerped[index_xyz][2] * (1.0f / 40.0f) - r_newrefdef.time * 0.5f);
  210.                     qglVertex3fv( s_lerped[index_xyz] );
  211.                 } while (--count);
  212.             }
  213.             else
  214.             {
  215.                 do
  216.                 {
  217.                     // texture coordinates come from the draw list
  218.                     qglTexCoord2f (((float *)order)[0], ((float *)order)[1]);
  219.                     index_xyz = order[2];
  220.  
  221.                     order += 3;
  222.  
  223.                     // normals and vertexes come from the frame list
  224.                     qglArrayElement( index_xyz );
  225.  
  226.                 } while (--count);
  227.             }
  228.             qglEnd ();
  229.         }
  230.  
  231.         if ( qglUnlockArraysEXT != 0 )
  232.             qglUnlockArraysEXT();
  233.     }
  234.     else
  235.     {
  236.         if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) ) // c14 added this line
  237.             qglColor4f( shadelight[0], shadelight[1], shadelight[2], alpha);
  238.  
  239.         while (count = *order++)
  240.         {
  241.  
  242.             // get the vertex count and primitive type
  243.             if (count < 0)
  244.             {
  245.                 count = -count;
  246.                 qglBegin (GL_TRIANGLE_FAN);
  247.             }
  248.             else
  249.             {
  250.                 qglBegin (GL_TRIANGLE_STRIP);
  251.             }
  252.  
  253.             //if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE ) )
  254.             if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) ) // c14 added this line.
  255.             {
  256.                 do
  257.                 {
  258.                     index_xyz = order[2];
  259.                     order += 3;
  260.  
  261.                     qglTexCoord2f (
  262.                         (s_lerped[index_xyz][1] + s_lerped[index_xyz][0]) * (1.0f / 40.0f),
  263.                         s_lerped[index_xyz][2] * (1.0f / 40.0f) - r_newrefdef.time * 0.5f);
  264.                     qglVertex3fv (s_lerped[index_xyz]);
  265.                 } while (--count);
  266.             }
  267.             else
  268.             {
  269.                 do
  270.                 {
  271.                     // texture coordinates come from the draw list
  272.                     qglTexCoord2f (((float *)order)[0], ((float *)order)[1]);
  273.                     index_xyz = order[2];
  274.                     order += 3;
  275.  
  276.                     // normals and vertexes come from the frame list
  277.                     l = shadedots[verts[index_xyz].lightnormalindex];
  278.                     
  279.                     qglColor4f (l*shadelight[0], l*shadelight[1], l*shadelight[2], alpha);
  280.                     qglVertex3fv (s_lerped[index_xyz]);
  281.                 } while (--count);
  282.             }
  283.  
  284.             qglEnd ();
  285.         }
  286.     }
  287.  
  288. //    if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE ) )
  289.     // PMM - added double damage shell
  290.     if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) )
  291.         qglEnable( GL_TEXTURE_2D );
  292. }
  293.  
  294.  
  295. #if 1
  296. /*
  297. =============
  298. GL_DrawAliasShadow
  299. =============
  300. */
  301. extern    vec3_t            lightspot;
  302.  
  303. void GL_DrawAliasShadow (dmdl_t *paliashdr, int posenum)
  304. {
  305.     dtrivertx_t    *verts;
  306.     int        *order;
  307.     vec3_t    point;
  308.     float    height, lheight;
  309.     int        count;
  310.     daliasframe_t    *frame;
  311.  
  312.     lheight = currententity->origin[2] - lightspot[2];
  313.  
  314.     frame = (daliasframe_t *)((byte *)paliashdr + paliashdr->ofs_frames 
  315.         + currententity->frame * paliashdr->framesize);
  316.     verts = frame->verts;
  317.  
  318.     height = 0;
  319.  
  320.     order = (int *)((byte *)paliashdr + paliashdr->ofs_glcmds);
  321.  
  322.     height = -lheight + 1.0;
  323.  
  324.     while (count = *order++)
  325.     {
  326.         // get the vertex count and primitive type
  327.         if (count < 0)
  328.         {
  329.             count = -count;
  330.             qglBegin (GL_TRIANGLE_FAN);
  331.         }
  332.         else
  333.             qglBegin (GL_TRIANGLE_STRIP);
  334.  
  335.         do
  336.         {
  337.             // normals and vertexes come from the frame list
  338.             VectorCopy( s_lerped[order[2]], point  );
  339.  
  340.             point[0] -= shadevector[0]*(point[2]+lheight);
  341.             point[1] -= shadevector[1]*(point[2]+lheight);
  342.             point[2] = height;
  343.  
  344.             qglVertex3fv (point);
  345.  
  346.             order += 3;
  347.         } while (--count);
  348.  
  349.         qglEnd ();
  350.     }    
  351. }
  352.  
  353. #endif
  354.  
  355. /*
  356. ** R_CullAliasModel
  357. */
  358. static qboolean R_CullAliasModel( vec3_t bbox[8], entity_t *e )
  359. {
  360.     int i;
  361.     vec3_t        mins, maxs;
  362.     dmdl_t        *paliashdr;
  363.     vec3_t        vectors[3];
  364.     vec3_t        thismins, oldmins, thismaxs, oldmaxs;
  365.     daliasframe_t *pframe, *poldframe;
  366.     vec3_t angles;
  367.  
  368.     paliashdr = (dmdl_t *)currentmodel->extradata;
  369.  
  370.     if ( ( e->frame >= paliashdr->num_frames ) || ( e->frame < 0 ) )
  371.     {
  372.         Com_Printf ("R_CullAliasModel %s: no such frame %d\n", 
  373.             currentmodel->name, e->frame);
  374.         e->frame = 0;
  375.     }
  376.     if ( ( e->oldframe >= paliashdr->num_frames ) || ( e->oldframe < 0 ) )
  377.     {
  378.         Com_Printf ("R_CullAliasModel %s: no such oldframe %d\n", 
  379.             currentmodel->name, e->oldframe);
  380.         e->oldframe = 0;
  381.     }
  382.  
  383.     pframe = ( daliasframe_t * ) ( ( byte * ) paliashdr + 
  384.                                       paliashdr->ofs_frames +
  385.                                       e->frame * paliashdr->framesize);
  386.  
  387.     poldframe = ( daliasframe_t * ) ( ( byte * ) paliashdr + 
  388.                                       paliashdr->ofs_frames +
  389.                                       e->oldframe * paliashdr->framesize);
  390.  
  391.     /*
  392.     ** compute axially aligned mins and maxs
  393.     */
  394.     if ( pframe == poldframe )
  395.     {
  396.         for ( i = 0; i < 3; i++ )
  397.         {
  398.             mins[i] = pframe->translate[i];
  399.             maxs[i] = mins[i] + pframe->scale[i]*255;
  400.         }
  401.     }
  402.     else
  403.     {
  404.         for ( i = 0; i < 3; i++ )
  405.         {
  406.             thismins[i] = pframe->translate[i];
  407.             thismaxs[i] = thismins[i] + pframe->scale[i]*255;
  408.  
  409.             oldmins[i]  = poldframe->translate[i];
  410.             oldmaxs[i]  = oldmins[i] + poldframe->scale[i]*255;
  411.  
  412.             if ( thismins[i] < oldmins[i] )
  413.                 mins[i] = thismins[i];
  414.             else
  415.                 mins[i] = oldmins[i];
  416.  
  417.             if ( thismaxs[i] > oldmaxs[i] )
  418.                 maxs[i] = thismaxs[i];
  419.             else
  420.                 maxs[i] = oldmaxs[i];
  421.         }
  422.     }
  423.  
  424.     /*
  425.     ** compute a full bounding box
  426.     */
  427.     for ( i = 0; i < 8; i++ )
  428.     {
  429.         vec3_t   tmp;
  430.  
  431.         if ( i & 1 )
  432.             tmp[0] = mins[0];
  433.         else
  434.             tmp[0] = maxs[0];
  435.  
  436.         if ( i & 2 )
  437.             tmp[1] = mins[1];
  438.         else
  439.             tmp[1] = maxs[1];
  440.  
  441.         if ( i & 4 )
  442.             tmp[2] = mins[2];
  443.         else
  444.             tmp[2] = maxs[2];
  445.  
  446.         VectorCopy( tmp, bbox[i] );
  447.     }
  448.  
  449.     /*
  450.     ** rotate the bounding box
  451.     */
  452.     VectorCopy( e->angles, angles );
  453.     angles[YAW] = -angles[YAW];
  454.     AngleVectors( angles, vectors[0], vectors[1], vectors[2] );
  455.  
  456.     for ( i = 0; i < 8; i++ )
  457.     {
  458.         vec3_t tmp;
  459.  
  460.         VectorCopy( bbox[i], tmp );
  461.  
  462.         bbox[i][0] = DotProduct( vectors[0], tmp );
  463.         bbox[i][1] = -DotProduct( vectors[1], tmp );
  464.         bbox[i][2] = DotProduct( vectors[2], tmp );
  465.  
  466.         VectorAdd( e->origin, bbox[i], bbox[i] );
  467.     }
  468.  
  469.     {
  470.         int p, f, aggregatemask = ~0;
  471.  
  472.         for ( p = 0; p < 8; p++ )
  473.         {
  474.             int mask = 0;
  475.  
  476.             for ( f = 0; f < 4; f++ )
  477.             {
  478.                 float dp = DotProduct( frustum[f].normal, bbox[p] );
  479.  
  480.                 if ( ( dp - frustum[f].dist ) < 0 )
  481.                 {
  482.                     mask |= ( 1 << f );
  483.                 }
  484.             }
  485.  
  486.             aggregatemask &= mask;
  487.         }
  488.  
  489.         if ( aggregatemask )
  490.         {
  491.             return true;
  492.         }
  493.  
  494.         return false;
  495.     }
  496. }
  497.  
  498. /*
  499. =================
  500. R_DrawAliasModel
  501.  
  502. =================
  503. */
  504. void R_DrawAliasModel (entity_t *e)
  505. {
  506.     int            i;
  507.     dmdl_t        *paliashdr;
  508.     vec3_t        bbox[8];
  509.     image_t        *skin;
  510.  
  511.     if ( !( e->flags & RF_WEAPONMODEL ) )
  512.     {
  513.         if ( R_CullAliasModel( bbox, e ) )
  514.             return;
  515.     }
  516.     else
  517.     {
  518.         if ( r_lefthand->value == 2 )
  519.             return;
  520.     }
  521.  
  522.     paliashdr = (dmdl_t *)currentmodel->extradata;
  523.  
  524.     //
  525.     // get lighting information
  526.     //
  527.     // PMM - rewrote, reordered to handle new shells & mixing
  528.     // PMM - 3.20 code .. replaced with original way of doing it to keep mod authors happy
  529.     //
  530.     if ( currententity->flags & ( RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE ) )
  531.     {
  532.         VectorClear (shadelight);
  533.         if (currententity->flags & RF_SHELL_HALF_DAM)
  534.         {
  535.                 shadelight[0] = 0.56;
  536.                 shadelight[1] = 0.59;
  537.                 shadelight[2] = 0.45;
  538.         }
  539.         if ( currententity->flags & RF_SHELL_DOUBLE )
  540.         {
  541.             shadelight[0] = 0.9;
  542.             shadelight[1] = 0.7;
  543.         }
  544.         if ( currententity->flags & RF_SHELL_RED )
  545.             shadelight[0] = 1.0;
  546.         if ( currententity->flags & RF_SHELL_GREEN )
  547.         {
  548.             shadelight[1] = 1.0;
  549.             shadelight[2] = 1.0;  //make it more of a cyan color...
  550.         }
  551.         if ( currententity->flags & RF_SHELL_BLUE )
  552.         {
  553.             shadelight[2] = 1.0;
  554.             shadelight[1] = 0.4;
  555.             shadelight[0] = 0.6; //we want this to look like electricity
  556.         }
  557.     }
  558.     else if ( currententity->flags & RF_FULLBRIGHT )
  559.     {
  560.         for (i=0 ; i<3 ; i++)
  561.             shadelight[i] = 1.0;
  562.     }
  563.     else
  564.     {
  565.         R_LightPoint (currententity->origin, shadelight);
  566.  
  567.         // player lighting hack for communication back to server
  568.         // big hack!
  569.         if ( currententity->flags & RF_WEAPONMODEL )
  570.         {
  571.             // pick the greatest component, which should be the same
  572.             // as the mono value returned by software
  573.             if (shadelight[0] > shadelight[1])
  574.             {
  575.                 if (shadelight[0] > shadelight[2])
  576.                     r_lightlevel->value = 150*shadelight[0];
  577.                 else
  578.                     r_lightlevel->value = 150*shadelight[2];
  579.             }
  580.             else
  581.             {
  582.                 if (shadelight[1] > shadelight[2])
  583.                     r_lightlevel->value = 150*shadelight[1];
  584.                 else
  585.                     r_lightlevel->value = 150*shadelight[2];
  586.             }
  587.  
  588.         }
  589.         
  590.         if ( gl_monolightmap->string[0] != '0' )
  591.         {
  592.             float s = shadelight[0];
  593.  
  594.             if ( s < shadelight[1] )
  595.                 s = shadelight[1];
  596.             if ( s < shadelight[2] )
  597.                 s = shadelight[2];
  598.  
  599.             shadelight[0] = s;
  600.             shadelight[1] = s;
  601.             shadelight[2] = s;
  602.         }
  603.     }
  604.  
  605.     if ( currententity->flags & RF_MINLIGHT )
  606.     {
  607.         for (i=0 ; i<3 ; i++)
  608.             if (shadelight[i] > 0.1)
  609.                 break;
  610.         if (i == 3)
  611.         {
  612.             shadelight[0] = 0.1;
  613.             shadelight[1] = 0.1;
  614.             shadelight[2] = 0.1;
  615.         }
  616.     }
  617.  
  618.     if ( currententity->flags & RF_GLOW )
  619.     {    // bonus items will pulse with time
  620.         float    scale;
  621.         float    min;
  622.  
  623.         scale = 0.1 * sin(r_newrefdef.time*7);
  624.         for (i=0 ; i<3 ; i++)
  625.         {
  626.             min = shadelight[i] * 0.8;
  627.             shadelight[i] += scale;
  628.             if (shadelight[i] < min)
  629.                 shadelight[i] = min;
  630.         }
  631.     }
  632.  
  633. // =================
  634. // PGM    ir goggles color override
  635.     if ( r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE)
  636.     {
  637.         shadelight[0] = 1.0;
  638.         shadelight[1] = 0.0;
  639.         shadelight[2] = 0.0;
  640.     }
  641. // PGM    
  642. // =================
  643.  
  644.     shadedots = r_avertexnormal_dots[((int)(currententity->angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)];
  645.     
  646.     //
  647.     // locate the proper data
  648.     //
  649.  
  650.     c_alias_polys += paliashdr->num_tris;
  651.  
  652.     //
  653.     // draw all the triangles
  654.     //
  655.     if (currententity->flags & RF_DEPTHHACK) // hack the depth range to prevent view model from poking into walls
  656.         qglDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin));
  657.  
  658.     if ( ( currententity->flags & RF_WEAPONMODEL ) && ( r_lefthand->value == 1.0F ) )
  659.     {
  660.         extern void MYgluPerspective( GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar );
  661.  
  662.         qglMatrixMode( GL_PROJECTION );
  663.         qglPushMatrix();
  664.         qglLoadIdentity();
  665.         qglScalef( -1, 1, 1 );
  666.         MYgluPerspective( r_newrefdef.fov_y, ( float ) r_newrefdef.width / r_newrefdef.height,  4,  4096);
  667.         qglMatrixMode( GL_MODELVIEW );
  668.  
  669.         qglCullFace( GL_BACK );
  670.     }
  671.  
  672.     qglPushMatrix ();
  673.     e->angles[PITCH] = -e->angles[PITCH];    // sigh.
  674.     R_RotateForEntity (e);
  675.     e->angles[PITCH] = -e->angles[PITCH];    // sigh.
  676.  
  677.     // select skin
  678.     if (currententity->skin)
  679.         skin = currententity->skin;    // custom player skin
  680.     else
  681.     {
  682.         if (currententity->skinnum >= MAX_MD2SKINS)
  683.             skin = currentmodel->skins[0];
  684.         else
  685.         {
  686.             skin = currentmodel->skins[currententity->skinnum];
  687.             if (!skin)
  688.                 skin = currentmodel->skins[0];
  689.         }
  690.     }
  691.     if (!skin)
  692.         skin = r_notexture;    // fallback...
  693.     GL_Bind(skin->texnum);
  694.  
  695.     // draw it
  696.  
  697.     qglShadeModel (GL_SMOOTH);
  698.  
  699.     GL_TexEnv( GL_MODULATE );
  700.     if ( currententity->flags & RF_TRANSLUCENT )
  701.     {
  702.         qglEnable (GL_BLEND);
  703.     }
  704.  
  705.  
  706.     if ( (currententity->frame >= paliashdr->num_frames) 
  707.         || (currententity->frame < 0) )
  708.     {
  709.         Com_Printf ("R_DrawAliasModel %s: no such frame %d\n",
  710.             currentmodel->name, currententity->frame);
  711.         currententity->frame = 0;
  712.         currententity->oldframe = 0;
  713.     }
  714.  
  715.     if ( (currententity->oldframe >= paliashdr->num_frames)
  716.         || (currententity->oldframe < 0))
  717.     {
  718.         Com_Printf ("R_DrawAliasModel %s: no such oldframe %d\n",
  719.             currentmodel->name, currententity->oldframe);
  720.         currententity->frame = 0;
  721.         currententity->oldframe = 0;
  722.     }
  723.  
  724.     if ( !r_lerpmodels->value )
  725.         currententity->backlerp = 0;
  726.     GL_DrawAliasFrameLerp (paliashdr, currententity->backlerp);
  727.  
  728.     GL_TexEnv( GL_REPLACE );
  729.     qglShadeModel (GL_FLAT);
  730.  
  731.     qglPopMatrix ();
  732.  
  733. #if 0
  734.     qglDisable( GL_CULL_FACE );
  735.     qglPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
  736.     qglDisable( GL_TEXTURE_2D );
  737.     qglBegin( GL_TRIANGLE_STRIP );
  738.     for ( i = 0; i < 8; i++ )
  739.     {
  740.         qglVertex3fv( bbox[i] );
  741.     }
  742.     qglEnd();
  743.     qglEnable( GL_TEXTURE_2D );
  744.     qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
  745.     qglEnable( GL_CULL_FACE );
  746. #endif
  747.  
  748.     if ( ( currententity->flags & RF_WEAPONMODEL ) && ( r_lefthand->value == 1.0F ) )
  749.     {
  750.         qglMatrixMode( GL_PROJECTION );
  751.         qglPopMatrix();
  752.         qglMatrixMode( GL_MODELVIEW );
  753.         qglCullFace( GL_FRONT );
  754.     }
  755.  
  756.     if ( currententity->flags & RF_TRANSLUCENT )
  757.     {
  758.         qglDisable (GL_BLEND);
  759.     }
  760.  
  761.     if (currententity->flags & RF_DEPTHHACK)
  762.         qglDepthRange (gldepthmin, gldepthmax);
  763.  
  764. #if 1
  765.     if (gl_shadows->value && !(currententity->flags & (RF_TRANSLUCENT | RF_WEAPONMODEL)))
  766.     {
  767.         float an = -currententity->angles[1]/180*M_PI;
  768.         shadevector[0] = cos(an);
  769.         shadevector[1] = sin(an);
  770.         shadevector[2] = 1;
  771.         VectorNormalize (shadevector);
  772.  
  773.         qglPushMatrix ();
  774.         R_RotateForEntity (e);
  775.         qglDisable (GL_TEXTURE_2D);
  776.         qglEnable (GL_BLEND);
  777.         qglColor4f (0,0,0,0.5);
  778.         GL_DrawAliasShadow (paliashdr, currententity->frame );
  779.         qglEnable (GL_TEXTURE_2D);
  780.         qglDisable (GL_BLEND);
  781.         qglPopMatrix ();
  782.     }
  783. #endif
  784.  
  785.     qglColor4f (1,1,1,1);
  786. }
  787.  
  788.  
  789.